<?php

namespace services\base;

use Yii;
use common\models\member\Member;
use common\models\member\Attr;
use common\models\base\Project;
use common\helpers\RedisHelper;
use common\components\Service;
use yii\data\Pagination;
use yii\db\Expression;

/**
 * Class ProjectService
 * @package services\base
 */
class ProjectService extends Service
{
    /**
     * @param int $id
     * @return Project|null
     */
    public function findById(int $id = 0): ?Project
    {
        return Project::find()->where(['id' => $id])->one();
    }

    /**
     * 获取列表
     * @param array $condition
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getList(array $condition = [])
    {
        $query = Project::find();

        isset($condition['column']) && $query->select($condition['column']);

        // select
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);
        isset($condition['id']) && $query->andWhere(['id' => $condition['id']]);

        // order
        isset($condition['orderBy']) && $query->orderBy($condition['orderBy']);

        if (isset($condition['indexBy']) && $condition['indexBy']) {
            $query->indexBy($condition['indexBy']);
        }

        return $query->orderBy(['status' => SORT_DESC, 'sort' => SORT_ASC])->asArray()->all();
    }

    /**
     * 获取项目列表
     *
     * @param $page
     * @param $limit
     * @return array
     * @author chenyuebin
     */
    public static function proList($page, $limit)
    {
        $query = Project::find()
            ->where(['in', 'status', [Project::STATUS_ENABLE, Project::STATUS_INVALID]])
            ->select(['*',
                new Expression('FROM_UNIXTIME(`created_at`, "%Y-%m-%d %H：%i") created_at'),
                new Expression('FROM_UNIXTIME(`updated_at`, "%Y-%m-%d %H：%i") updated_at')
            ]);
        $pagination = new Pagination([
            'defaultPageSize' => $limit,
            'totalCount' => $query->count(),
        ]);
        $ret = $query->offset($pagination->offset)
            ->limit($pagination->limit)
            ->orderBy(['status' => SORT_DESC, 'sort' => SORT_ASC])
            ->asArray()
            ->all();
        foreach ($ret as $key => $value) {
            $memberArr = implode(";", self::proMembers($value['id']));
            $ret[$key]['members'] = $memberArr;
        }
        return [
            'list' => $ret,
            'total' => (int)$pagination->totalCount,
            'pageSize' => (int)$limit,
            'page' => (int)$page
        ];
    }

    /**
     * 获取项目下的人员
     * @param $id
     * @return array|\yii\db\ActiveRecord[]
     * @author chenyuebin
     */
    public static function proMembers($id)
    {
        $res = Attr::find()
            ->alias('ma')
            ->leftJoin(Member::tableName() . ' m', 'ma.member_id=m.id')
            ->where(['status' => 1])
            ->andWhere(
                new Expression("FIND_IN_SET({$id},ma.project_id)")
            )
            ->select(['realname'])
            ->asArray()
            ->column();
        return $res;
    }

    /**
     * 检查项目是否重复
     *
     * @param array $condition
     * @return bool
     * @author chenyuebin
     */
    public static function checkPro(array $condition)
    {
        return Project::find()
            ->where($condition)
            ->andWhere(['!=', 'status', Project::STATUS_DELETE])
            ->exists();
    }

    /**
     * 新增项目
     *
     * @param $params
     * @return bool
     * @author chenyuebin
     */
    public static function proCreate(array $params)
    {
        //查询新建项目是否重名
        $exists = self::checkPro(['name' => $params['name']]);
        if ($exists) {
            return ['code' => 422, 'message' => '创建失败项目名重复',];
        }
        $project = new Project();

        foreach ($params as $key => $value) {
            $project->$key = $value;
        }
        $project->name_sx = $project->name ? strtolower($project->name) : '';
        if ($project->save()) {
            RedisHelper::setProject($project);
            return ['code' => 200, 'message' => 'success',];
        }

        return ['code' => 422, 'message' => '创建失败',];
    }

    /**
     * 编辑项目
     *
     * @param $params
     * @param $id
     * @return array
     * @author chenyuebin
     */
    public static function proUpdate(array $params, int $id)
    {
        //查询是否重命名
        $model = Project::find()->select('id')
            ->where(['name' => $params['name']])
            ->andWhere(['!=', 'status', Project::STATUS_DELETE])
            ->one();
        if ($model && $model->id != $id) {
            return ['code' => 422, 'message' => '项目名重复',];
        }
        $project = Project::findOne($id);

        foreach ($params as $key => $value) {
            $project->$key = $value;
        }
        $project->name_sx = $project->name ? strtolower($project->name) : '';
        if ($project->save()) {
            RedisHelper::setProject($project);
            return ['code' => 200, 'message' => 'success',];
        }

        return ['code' => 422, 'message' => '更新失败',];
    }


    /**
     * 编辑项目状态
     *
     * @param int $id
     * @param int $status
     * @return array
     * @throws \Exception
     * @author wangxiang
     */
    public static function changeStatus(int $id, int $status)
    {
        $model = Project::findOne($id);
        $model->status = $status;
        if (!$model->save()) {
            throw new \Exception(json_encode($model->errors), 500);
        }
        RedisHelper::setProject($model);
        return ['status' => $status, 'id' => $id];
    }

    public static function deleteProject($id)
    {
        $model = Project::findOne($id);
        if ($model) {
            $model->status = Project::STATUS_DELETE;
            $model->save();
            RedisHelper::setProject($model);
            return true;
        }
        return false;
    }

    /**
     * 根据缩写获取项目信息
     * @param array $params
     * @return array
     */
    public function getInfoByNameSx(array $params): array
    {
        $res = Project::find()
            ->where(['name_sx' => $params['name_sx']])
            ->asArray()
            ->one();
        return $res ?: [];
    }

    /**
     * 获取项目列表
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getProjectList(): array
    {
        return $this->getList([
            'column' => ['id', 'name_sx'],
            'status' => Project::STATUS_ENABLE
        ]);
    }
}
